package com.wy.verticaldarglistview;

import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.widget.FrameLayout;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.customview.widget.ViewDragHelper;

/**
 * Time:8/12/21
 * Author:ypf
 * Description:
 */
public class VerticalDargListView extends FrameLayout {


    private String TAG = "VerticalDargListView";

    private ViewDragHelper mViewDragHelper;

    private View mDragListView;
    private View mMenuView;

    //后面菜单的高度
    private int mMenuHeight;
    private boolean mMenuIsOpen = false;

    public VerticalDargListView(@NonNull Context context) {
        this(context, null, 0);
    }

    public VerticalDargListView(@NonNull Context context, @Nullable AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public VerticalDargListView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        mViewDragHelper = ViewDragHelper.create(this, mViewDragHelperCallback);
    }

    @Override
    protected void onFinishInflate() {
        super.onFinishInflate();

        int childCount = getChildCount();

        if (childCount != 2) {
            throw new RuntimeException("RuntimeException 必须放两个子布局");
        }

        mDragListView = getChildAt(1);

    }


    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        if (changed) {
            mMenuView = getChildAt(0);
            mMenuHeight = mMenuView.getHeight();
        }
    }

    @Override
    public boolean onInterceptHoverEvent(MotionEvent event) {
        return mViewDragHelper.shouldInterceptTouchEvent(event);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mViewDragHelper.processTouchEvent(event);
        return true;
    }

    private ViewDragHelper.Callback mViewDragHelperCallback = new ViewDragHelper.Callback() {

        //拖动被松开
        @Override
        public void onViewReleased(@NonNull View releasedChild, float xvel, float yvel) {
            super.onViewReleased(releasedChild, xvel, yvel);

            if (releasedChild == mDragListView) {

                int top = mDragListView.getTop();

                if (top > mMenuHeight / 2) {
                    //滚动到菜单的高度（打开）
                    mViewDragHelper.settleCapturedViewAt(0, mMenuHeight);
                    mMenuIsOpen = true;
                } else {
                    //滚动到0的高度（关闭）
                    mViewDragHelper.settleCapturedViewAt(0, 0);
                    mMenuIsOpen = false;
                }
                invalidate();
                Log.i(TAG, "onViewReleased xvel ->" + xvel + " ,yvel ->" + yvel);

            }

        }

        //指定子view是否可以拖动，true是可以拖动
        @Override
        public boolean tryCaptureView(@NonNull View child, int pointerId) {
            Log.i(TAG, "tryCaptureView pointerId ->" + pointerId);
            return mDragListView == child;
        }

        @Override
        public int clampViewPositionVertical(@NonNull View child, int top, int dy) {
            Log.i(TAG, "clampViewPositionVertical top ->" + top + " ,dy ->" + dy + ",mMenuHeight:" + mMenuHeight);
            if (top < 0) {
                top = 0;
            }
            if (top >= mMenuHeight) {
                top = mMenuHeight;
            }
            //step3:拖动的范围只能是菜单的高度
            return top;
        }
    };

    //现象是listview可以滑动，菜单滑动没有效果了
    private float mDownY;

    //ViewDragHelper: Ignoring pointerId=0 because ACTION_DOWN was not received for this pointer before ACTION_MOVE.
    // It likely happened because  ViewDragHelper did not receive all the events in the event stream.
    //VDLV.onInterceptTouchEvent().DOWN -> LV.onTouch() -> VDLV.onInterceptTouchEvent().MOVE  ->
    @Override
    public boolean onInterceptTouchEvent(MotionEvent ev) {

        //菜单打开要全部拦截
        if (mMenuIsOpen) {
            return true;
        }

        //向下滑动拦截，不要给listview做处理
        //谁拦截谁 父view拦截子view，但是子view可以调这个方法
        //requestDisallowInterceptTouchEvent 请求父view不要拦截，改变的其实是mGroupFlags的值

        switch (ev.getAction()) {
            case MotionEvent.ACTION_DOWN:
                mDownY = ev.getY();
                //让DragHelper调用一次完整的事件
                mViewDragHelper.processTouchEvent(ev);
                break;
            case MotionEvent.ACTION_MOVE:
                float moveY = ev.getY();
                if (moveY - mDownY > 0 && mDragListView.getTop() == 0) {
                    //向下滑动 && 滚动到了顶部，拦截不让listview做处理
                    return true;
                }
                break;
        }
        return super.onInterceptTouchEvent(ev);
    }

    //响应滚动
    @Override
    public void computeScroll() {
        super.computeScroll();
        if (mViewDragHelper.continueSettling(true)) {
            invalidate();
        }
    }

}
